package com.aw.baselib.net.callback;

import com.aw.baselib.R;
import com.aw.baselib.base.AwBaseApplication;
import com.aw.baselib.base.AwResponseBean;
import com.aw.baselib.bean.rx.EventReLoginType;
import com.aw.baselib.net.error.ApiException;
import com.aw.baselib.util.AwLog;
import com.google.gson.JsonParseException;

import org.greenrobot.eventbus.EventBus;
import org.json.JSONException;

import java.net.ConnectException;
import java.net.SocketTimeoutException;
import java.net.UnknownHostException;

import io.reactivex.observers.ResourceObserver;
import retrofit2.HttpException;

/**
 * @author liushikai
 * @version 1
 * @date 2018/12/17
 * @describe 自定义的默认观察者
 */
public class AwApiObserver<T extends AwResponseBean> extends ResourceObserver<T> {

    public static final int UNKNOWN_CODE = -1;
    private AwApiCallback<T> mRspCallback;

    /**
     * 构造方法
     */
    public AwApiObserver(AwApiCallback<T> apiCallback) {
        mRspCallback = apiCallback;
    }

    @Override
    protected void onStart() {
        super.onStart();
        if (null == mRspCallback) {
            return;
        }
        mRspCallback.onStart();
    }

    /**
     * 请求有结果的时候，根据返回的结果码判断是否成功调用相应的方法
     *
     * @param rspBean 服务器返回的数据
     */
    @Override
    public void onNext(T rspBean) {
        if(null == mRspCallback) {
            AwLog.d("===AwRspConsumer callback is null, return");
            return;
        } else {
            if(rspBean == null) {
                mRspCallback.onFail(UNKNOWN_CODE, AwBaseApplication.getInstance().getString(R.string.common_server_return_empty_data));
            } else if(rspBean.isTokenError()) {
                EventBus.getDefault().postSticky(new EventReLoginType(null));
            } else if(rspBean.isSuccess()) {
                mRspCallback.onSuccess((T) rspBean.getData());
            } else {
                mRspCallback.onFail(rspBean.getCode(), rspBean.getMsg());
            }
            mRspCallback.onCompleted();
        }
    }

    /**
     * 请求超时或者是连接服务器失败（服务器响应结果是404或502及其他错误时），根据错误匹配出响应的信息。
     *
     */
    @Override
    public void onError(Throwable e) {
        AwLog.d("Retrofit网络请求", "Retrofit处理服务器响应数据:" + e.getMessage());
        e.printStackTrace();
        if (null == mRspCallback) {
            return;
        }
        if (e instanceof HttpException || e instanceof UnknownHostException) {
            mRspCallback.onFail(UNKNOWN_CODE, AwBaseApplication.getInstance().getString(R.string.common_net_server_abnormal_request));
        } else if(e instanceof SocketTimeoutException) {
            mRspCallback.onFail(UNKNOWN_CODE, AwBaseApplication.getInstance().getString(R.string.common_net_server_abnormal_timeout));
        } else if(e instanceof ConnectException) {
            mRspCallback.onFail(UNKNOWN_CODE, AwBaseApplication.getInstance().getString(R.string.common_net_server_abnormal_connect));
        } else if(e instanceof JsonParseException
                || e instanceof JSONException
                || e instanceof android.net.ParseException) {
            mRspCallback.onFail(UNKNOWN_CODE, AwBaseApplication.getInstance().getString(R.string.common_net_server_abnormal_parse));
        } else if(e instanceof ApiException) {
            ApiException exception = (ApiException) e;
            if (exception.isTokenExpried()) {
                //处理token失效对应的逻辑
                EventBus.getDefault().postSticky(new EventReLoginType(null));
            } else {
                mRspCallback.onFail(exception.getErrorCode(), exception.getMsg());
            }

        } else {
            if (e.getMessage() != null && e.getMessage().contains("failed") || e.getMessage().contains("Failed")) {
                mRspCallback.onFail(UNKNOWN_CODE, AwBaseApplication.getInstance().getString(R.string.common_net_abnormal));
            } else {
                mRspCallback.onFail(UNKNOWN_CODE, e.getMessage());
            }
        }
        onComplete();
    }


    /**
     * 请求异常
     *
     * @param reason 异常代号
     */
    public void onException(ExceptionReason reason) {
        switch (reason) {
            case CONNECT_ERROR:
                //连接错误
                //ToastUtils.showLongToast(MyApp.CONTEXT, R.string.connect_error);
                break;
            case CONNECT_TIMEOUT:
                //连接超时
                //ToastUtils.showLongToast(MyApp.CONTEXT, R.string.connect_timeout);
                break;
            case BAD_NETWORK:
                //网络问题
                //ToastUtils.showLongToast(MyApp.CONTEXT, R.string.bad_network);
                break;
            case PARSE_ERROR:
                //解析数据失败
                //ToastUtils.showLongToast(MyApp.CONTEXT, R.string.parse_error);
                break;
            case UNKNOWN_ERROR:
            default:
                //未知错误
                //ToastUtils.showLongToast(MyApp.CONTEXT, R.string.unknown_error);
                break;
        }
    }

    /**
     * 请求网络失败原因
     */
    public enum ExceptionReason {
        /**
         * 解析数据失败
         */
        PARSE_ERROR,
        /**
         * 网络问题
         */
        BAD_NETWORK,
        /**
         * 连接错误
         */
        CONNECT_ERROR,
        /**
         * 连接超时
         */
        CONNECT_TIMEOUT,
        /**
         * 未知错误
         */
        UNKNOWN_ERROR,
    }

    /**
     * 请求完成后调用,在onNext之后
     * TODO
     */
    @Override
    public void onComplete() {
        if (null == mRspCallback) {
            return;
        }
        mRspCallback.onCompleted();
    }

}
